<?php
// 接口-盘点单
namespace interface\v1;

use verify;

class inventoryListClass extends index
{
	private const page        = 'inventory';
	private const table       = 'inventory_take';
	private const tableMx     = 'inventory_take_detail';
	private const tableRecord = 'inventory_record';
	private const title       = '盘点单';
	private const state       = ['草稿', '待确认', '已确认'];
	
	public function search()
	{
		$this->code         = 1;
		$this->resp['data'] = [
			'orderNo'     => '单据条码',
			'warehouseId' => find(['table' => 'warehouse', 'field' => 'id as value, name as text', 'where' => " coid = '" . self::$coid . "' AND state = '启用' "])['array'],
			'state'       => self::state,
		];
	}
	
	/**
	 * 列表
	 *
	 * @return void
	 */
	public function list(): void
	{
		//获取查询结果
		$where = " coid = '" . self::$coid . "' ";
		$equal = [
			'orderNo'     => $this->post('orderNo'),
			'warehouseId' => $this->post('warehouseId'),
		];
		$like  = [
			'type' => $this->post('type'),
		];
		// 兼容后台写法
		if ($this->post('state')) {
			$state = $this->post('state');
			switch ($state) {
				case '待盘点':
				case '部分盘点':
					if($state == '待盘点'){
						$cwhere = " AND `num` = 0 AND `orderId` NOT IN (SELECT distinct orderId FROM `inventory_take_detail` WHERE coid = '" . self::$coid . "' AND num > 0) ";
					}else{
						$cwhere = " AND `num` > 0 ";
					}
					$where          .= " AND id IN (SELECT orderId FROM `inventory_take_detail` WHERE coid = '" . self::$coid . "' $cwhere ) ";
					$equal['state'] = '待确认';
					break;
				case '已盘点':
					$equal['state'] = '已确认';
					break;
			}
		}
		$where .= search([
			"="    => $equal,
			"like" => $like,
		]);
		if ($this->post('orderDate')) {
			$where .= self::timeComparison($this->post('orderDate'), 'date', 'orderDate');
		}
		$page = $this->page(["table" => self::table, "where" => $where, "order" => "time desc"]);
		//数据分析
		$data['result'] = [];
		foreach ($page['array'] as $array) {
			$data['result'][] = [
				'id'          => $array['id'],
				'warehouse'   => $array['warehouse'],
				'warehouseId' => $array['warehouseId'],
				'mtype'       => self::getTypeName($array['type']),
				'brand'       => $array['brand'],
				'orderNo'     => $array['orderNo'],
				'orderDate'   => $array['orderDate'],
				'state'       => $array['state'],
			];
		}
		$data['page'] = $page['para'];
		//返回
		$this->code         = 1;
		$this->resp['data'] = $data;
	}
	
	public static function getTypeName($id): mixed
	{
		$type = query('material_type', "id = '$id'");
		if (!empty($type['pid'])) {
			$result = self::getTypeName($type['pid']);
			$name   = $result . '->' . $type['name'];
		} else {
			$name = $type['name'] ?? null;
		}
		return $name;
	}
	
	/**
	 * 新增编辑
	 */
	public function edit()
	{
		$field      = [
			'warehouseId' => $this->post('warehouseId'),
			'warehouse'   => $this->post('warehouse'),
			'type'        => $this->post('type'),
			'brand'       => $this->post('brand'),
			'text'        => $this->post('text'),
		];
		$annotation = [
			'warehouseId' => '仓库Id',
			'warehouse'   => '仓库名称',
			'type'        => '商品分类',
			'brand'       => '品牌',
			'text'        => '备注',
		];
		$rules      = [
			'warehouse'   => 'required',
			'warehouseId' => 'required',
		];
		// 校验是否符合规则
		$vt     = new verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$this->resp['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
			goto resp;
		} elseif (!$this->power(self::page, 'edit')) {
			$this->resp['warn'] = '你还没有编辑权限';
		} else {
			$and   = search([
				'='    => [
					'typeId' => $this->post('type'),
				],
				'like' => [
					'brand' => $this->post('brand'),
				],
			]);
			$where = " coid = '" . self::$coid . "' AND " . generateWhere(['warehouseId' => $field['warehouseId'],]);
			if ($and) {
				$where .= " and materialId IN (SELECT id FROM `material` WHERE 1=1 $and ) ";
			}
			$result = find([
				'field' => ' DISTINCT `materialSkuId`, IFNULL(sum(num), 0) total ',
				'table' => self::tableRecord,
				'where' => $where . ' GROUP BY materialSkuId',
			]);
			if (!$result['array']) {
				$this->resp['warn'] = '暂无该物料';
			} else {
				$this->startTrans();
				$isPass   = true;//事务通过标志
				$whereArr = $field;
				unset($whereArr['text'],);
				$where = generateWhere(array_merge($whereArr, ['coid' => self::$coid, 'state' => '待确认']));
				$info  = query(self::table, $where);
				if ($info['id']) {
					$this->resp['warn'] = '已存在相同盘点单';
				} else {
					$orderNo = self::generateCode(self::page,[
                        'prefix' => 'PD' . date('Ymd'),
                        'table'  => self::table,
                        'field'  => 'orderNo',
                        'where'  => " AND coid = '" . self::$coid . "' ",
                    ],$field);
					$id      = self::getId();
					$field   = array_merge($field, [
						'id'        => $id,
						'orderDate' => $this->date,
						'orderNo'   => $orderNo,
						'state'     => '待确认',
						'coid'      => self::$coid,
						'stid'      => $this->control['stid'],
					]);
					$warn    = static::insert(["table" => self::table, "field" => $field,]);
					if (!in_array($warn, ["新增成功", "更新成功"])) {
						$this->resp['warn'] = $warn;
						goto resp;
					}
					foreach ($result['array'] as $array) {
						$materialSku = query('material_sku', "id = '$array[materialSkuId]'");
						if (empty($materialSku['id'])) {
							continue;
						}
						$material     = query('material', "id = '$materialSku[materialId]'");
						$inventoryNum = inventoryBalanceClass::inventoryNum($materialSku['id'], $field['warehouseId']);
						//新增
						$warn = static::insert([
							"table" => self::tableMx,
							"field" => [
								'id'            => self::getId(),
								'coid'          => self::$coid,
								'orderId'       => $id,
								'orderNum'      => $inventoryNum,
								'materialId'    => $materialSku['materialId'],
								'materialSkuId' => $materialSku['id'],
								'num'           => 0,
								'unit'          => $material['unit'],
							],
						]);
						if (!in_array($warn, ['新增成功', '更新成功'])) {
							$isPass             = false;
							$this->resp['warn'] = $warn;
							break;
						}
					}
					if (in_array($warn, ["新增成功", "更新成功"]) && $isPass) {
						$this->commitTrans();
						//添加日志
						$type = mb_substr($warn, 0, 2, 'utf-8');
						$text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
						$this->logText(["type" => self::page, "text" => $text]);
						$this->code         = 1;
						$this->resp['data'] = $id;
					} else {
						$this->rollback();
					}
				}
			}
		}
		
		resp:
	}
	
	
	/**
	 * 确认
	 */
	public function confirmEdit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
		$field = [
			'state'       => '已确认',
			'confirmTime' => $this->time,
		];
		if (!$this->power(self::page, 'confirm')) {
			$this->resp['warn'] = '你还没有确认权限';
		} else {
			if (empty($info['id'])) {
				$this->resp['warn'] = '未找到此盘点单';
			} else {
				if ($info['state'] != '待确认') {
					$this->resp['warn'] = '此盘点单不是待确认状态，不能确认';
				} else {
					$this->resp['warn'] = update([
						"table" => self::table,
						"field" => $field,
						"where" => "id = '$info[id]'",
					]);
					if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
						auditingFollow([
							"type"   => "盘点单",
							"typeId" => $info['id'],
							"text"   => "【{$this->control['name']}】确认",
						]);
						self::generateInventory($info['id'], '盘盈单');
						self::generateInventory($info['id'], '盘亏单');
						//添加日志
						$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
						$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
						$this->logText(["type" => self::page, "text" => $text]);
						$this->resp['data'] = [
							'id'      => $info['id'],
							'orderNo' => $info['orderNo'],
						];
						$this->code         = 1;
					}
				}
			}
		}
		
		resp:
	}
	
	/**
	 * 生成盘亏盘盈
	 *
	 * @return string
	 */
	private static function generateInventory($id, $type): string
	{
		$where = " orderId = '$id' ";
		if ($type == '盘盈单') {
			$mtype       = '其他入库';
			$prefix      = 'QTRK' . date('Ymd');
			$where       .= " AND num > orderNum ";
			$subCategory = '盘盈';
			$classify    = 1;
			$state       = '待入库';
            $page = 'inStockOther';
		} else {
			$mtype       = '其他出库';
			$prefix      = 'QTCK' . date('Ymd');
			$where       .= " AND num < orderNum ";
			$subCategory = '盘亏';
			$classify    = 0;
			$state       = '待出库';
            $page = 'outStockOther';
		}
		$total = self::total([
			'table' => 'inventory',
			'where' => [
				'sourceTable' => self::table,
				'sourceId'    => $id,
				'type'        => $mtype,
			],
		]);
		$info  = query(self::table, " id = '$id'");
		if (empty($info)) {
			return self::title . '不存在';
		} elseif ($total > 0) {
			return $mtype . '已存在此' . $type;
		} else {
			$result = find([
				'table' => self::tableMx,
				'where' => $where,
			]);
			if (self::is_null_array($result['array'])) {
				return self::title . '无法生成' . $type;
			} else {
				$inId = self::getId();
                $field = [
                    'id'          => $inId,
                    'coid'        => self::$coid,
                    'orderDate'   => date('Y-m-d'),
                    'type'        => $mtype,
                    'subCategory' => $subCategory,
                    'classify'    => $classify,
                    'sourceTable' => 'inventory_take',
                    'sourceId'    => $info['id'],
                    'warehouseId' => $info['warehouseId'],
                    'state'       => $state,
                    'stid'        => self::$stid,
                ];
                $userNo = self::generateCode($page,[
                    'prefix' => $prefix,
                    'table'  => 'inventory',
                    'where'  => " AND coid = '" . self::$coid . "' ",
                ],$field);
                $field['orderNo'] = $userNo;
				static::insert([
					'table' => 'inventory',
					'field' => $field,
				]);
				foreach ((array)$result['array'] as $value) {
					$price = inventoryBalanceClass::unitPrice($value['materialSkuId']);
					$num   = abs($value['num'] - $value['orderNum']);
					static::insert([
						'table' => 'inventory_detail',
						'field' => [
							'id'            => self::getId(),
							'coid'          => self::$coid,
							'orderId'       => $inId,
							'materialId'    => $value['materialId'],
							'materialSkuId' => $value['materialSkuId'],
							'orderNum'      => $value['orderNum'],
							'num'           => $num,
							'price'         => $price,
							'money'         => round($num * $price, 2),
							'unit'          => $value['unit'],
							'sourceTable'   => 'inventory_take_detail',
							'sourceId'      => $value['id'],
							'warehouseId'   => $info['warehouseId'],
						],
					]);
				}
				return $type . '生成成功';
			}
		}
	}
	
	
	/**
	 * 删除
	 *
	 * @return void
	 */
	public function delete(): void
	{
		$array = $this->post('listId') ?? $this->post('id');
		if (!$this->power(self::page, "del")) {
			$this->resp['warn'] = "你没有删除的权限";
		} elseif (empty($array)) {
			$this->resp['warn'] = "你一个数据都没有选择呢";
		} else {
			$text  = "";
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			foreach ($array as $id) {
				$info = query(self::table, " id = '$id' ");
				if ($info['state'] == '已出库') {
					$warn = "删除失败：已出库，暂不能删除";
				} else {
					//最后删除基本参数
					delete(["table" => self::table, "where" => " id = '$id' "]);
					delete(["table" => self::tableMx, "where" => " orderId = '$id' "]);
					delete(["table" => 'auditing_follow', "where" => " typeId = '$id' "]);
					//返回
					$warn = "删除成功";
					$x++;
				}
				$text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
			}
			//添加日志
			$text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
			$this->logText(["type" => self::page, "text" => $text]);
			$this->resp['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
			$this->code         = 1;
		}
	}
	
	/**
	 * 详情
	 *
	 * @return void
	 */
	public function detail()
	{
		$id   = $this->post('id');
		$info = query(self::table, "id = '" . $id . "'");
		if (empty($id)) {
			$this->resp['warn'] = "ID为空";
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = "未找到此" . self::title;
		} else {
			$audit  = find([
				'table' => 'auditing_follow',
				'where' => " typeId = '$info[id]'",
			]);
			$result = find([
				'table' => self::tableMx,
				'where' => " orderId = '$info[id]' ",
			]);
			$detail = $takeRecord = [];
			foreach ($result['array'] as $value) {
				$material    = query('material', " id = '$value[materialId]' ");
				$materialSku = query('material_sku', " id = '$value[materialSkuId]' ");
				$rid         = self::generateId([$value['orderId'], $value['materialSkuId']]);
				$temp        = find(['table' => 'auditing_follow', 'where' => "typeId = '$rid' AND type = '盘点单' order by time desc"])['array'];
				$detail[]    = [
					'id'           => $value['id'],
					'code'         => $material['code'],
					'name'         => $material['name'],
					'skuName'      => $materialSku['name'],
					'mtype'        => inventoryListClass::getTypeName($material['typeId']),
					'brand'        => $material['brand'],
					'model'        => $material['model'],
					'unit'         => $material['unit'],
					// 'price'        => $value['price'],
					'num'          => $value['num'],
					'inventoryNum' => $value['orderNum'],
					// 'total'        => $value['num'] * $value['price'],
				];
				if (!self::is_null_array($temp)) {
					$takeRecord = array_merge($takeRecord, $temp);
				}
			}
			$data['result'] = [
				'info'        => [
					'id'          => $info['id'],
					"orderDate"   => $info['orderDate'],
					'mtype'       => inventoryListClass::getTypeName($info['type']),
					'brand'       => $info['brand'],
					'warehouse'   => $info['warehouse'],
					'warehouseId' => $info['warehouseId'],
					"text"        => $info['text'],
					"orderNo"     => $info['orderNo'],
					"stName"      => self::findStaff($info['stid']),
					"stid"        => $info['stid'],
					"state"       => $info['state'],
				],
				'detail'      => $detail,
				'auditRecord' => $audit['array'],
				'takeRecord'  => $takeRecord ? self::my_sort($takeRecord, 'time', SORT_DESC, SORT_STRING) : [],
			];
			//返回
			$this->code         = 1;
			$this->resp['data'] = $data;
		}
	}
	
	/**
	 * 盘点
	 */
	public function putIn()
	{
		$id   = $this->post('id');
		$num  = $this->post('num');
		$info = query(self::tableMx, " id = '$id'");
		$res  = query(self::table, " id = '$info[orderId]' ");
		if (!$this->power(self::page, 'edit')) {
			$this->resp['warn'] = '你还没有盘点权限';
		} elseif (empty($res['id'])) {
			$this->resp['warn'] = '未找到此盘点单';
		} elseif (self::isNull($num)) {
			$this->resp['warn'] = '请填写数量';
		} elseif (!in_array($res['state'], ['待确认'])) {
			$this->resp['warn'] = '此盘点单不是待确认状态，无法盘点数量';
		} else {
			$this->resp['warn'] = static::update([
				"table" => self::tableMx,
				"field" => [
					'num' => $info['num'] + $num,
				],
				"where" => "id = '$info[id]'",
			]);
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				$material = query('material', " id = '$info[materialId]' ", 'code, name, brand, model');
				auditingFollow([
					"type"   => "盘点单",
					"typeId" => self::generateId([$info['orderId'], $info['materialSkuId']]),
					"text"   => "【{$this->control['name']}】通过【前端】盘点【{$material['name']}-{$material['brand']}-{$material['model']}】数量[$num]",
				]);
				$this->resp['data'] = $res['id'];
				$this->code         = 1;
			}
		}
		resp:
	}
	
}
